home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
421_01
/
zoom.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-16
|
11KB
|
595 lines
// ZOOM.CPP
#include <stdlib.h>
#include <math.h>
#include <dos.h>
#include "stdio.h"
#include "timer.h"
#include "vx.h"
#define SLOW 0
#define MSEKDELAY 50
//#define NOTUNE
//#define NODRAW
#define FRAMES 44 // Number of times the resolution is doubled
#define EXT 192 // Size of window, in pixels
#define ROUGHSPLITS 12
#define FRACX 0
#define FRACY 0
#if EXT>96
#define SLOW 0
#endif
extern timer_C timer;
extern vx_C vx;
extern byte *keypressed;
// GLOBALS
word zoomvramptr=0xa000;
static byte *bitdata[FRAMES-1],*frac1b,*frac2b,*frac3b,*frac1,*frac2,*frac3;
word datalengths[FRAMES-1];
word innerlen,innerleft,innertop,innerfac,inneradr,farfac;
byte startx,starty,nearstartx,nearstarty;
byte *globalbmp;
// SETZCOLORS
void setzcolors(void)
{
for (int teller=1; teller<256; teller++)
{
float r=sin(teller*1.2*M_PI/255);
float g=sin(teller*1.8*M_PI/255);
float b=sin(teller*2.4*M_PI/255);
r=fabs(r)*63;
g=fabs(g)*63;
b=fabs(b)*63;
vx.setrgb(teller,r,g,b);
}
}
// ROUGHSPLIT
void roughsplit(byte *from, byte *to,word stripno)
{
long from_ptr=(long)from;
long to_ptr=(long)to;
to_ptr+=EXT*stripno*(EXT/ROUGHSPLITS);
from_ptr+=(EXT/4)+(EXT/4)*EXT+(EXT*stripno*(EXT/ROUGHSPLITS)/2);
asm pusha
asm push ds
asm cld
asm les di,to_ptr
asm lds si,from_ptr
asm mov bx,es
asm mov ch,(EXT/ROUGHSPLITS)/2
nextline:
asm mov cl,EXT/2
nextpixel: // unroll!
asm lodsb
asm stosb
asm stosb
asm dec cl
asm jnz nextpixel
asm add di,EXT
asm add si,EXT/2
asm dec ch
asm jnz nextline
asm lds si,to_ptr
asm mov di,si
asm mov ax,EXT
asm add di,ax
asm mov dl,(EXT/ROUGHSPLITS)/2
twinline:
#if USE32BIT
asm mov cx,EXT/4
asm rep movsd
#else
asm mov cx,EXT/2
asm rep movsw
asm add si,ax
asm add di,ax
#endif
asm dec dl
asm jnz twinline
asm pop ds
asm popa
}
byte *datas,datamask,lastpopped;
// POPBIT
byte _fastcall popbit(void)
{
asm les bx,dword ptr datas
asm mov al,[es:bx]
asm and al,datamask
asm shr datamask,1
asm jnc ok
asm mov datamask,128
asm inc word ptr datas
ok:
}
// CTEST
void near _pascal ctest(int x,int y,byte len)
{
#ifdef NOTUNE
return;
#endif
static byte p,fac;
int yy,xx;
asm les bx,dword ptr datas // es = kontant ptr->datas
asm mov yy,2
newx:
asm mov xx,2
nextx:
asm les bx,dword ptr datas // es = kontant ptr->datas
asm mov al,[es:bx]
asm and al,datamask
asm shr datamask,1
asm jnc ok
asm mov datamask,128
asm inc word ptr datas
ok:
asm and al,al
asm jnz doit
goto staylow;
doit:
if (len>2)
{
static word nx,ny;
word len2=len;
len2>>=1;
nx=0;
ny=0;
if (xx==1)
nx=len2;
if (yy==1)
ny=len2;
ctest(x+nx,y+ny,len2);
}
else
{
byte color=0;
asm les bx,dword ptr datas // es = kontant ptr->datas
asm mov al,[es:bx]
asm and al,datamask
asm shr datamask,1
asm jnc againok
asm mov datamask,128
asm inc word ptr datas
againok:
asm and al,al
asm jz notvip
if (popbit())
color=1;
else
color=-1;
goto vipdone;
notvip:
color=0;
p=popbit();
fac=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (p)
color+=2;
else
{
color+=247;
if (color==247)
{
fac=1;
color=0;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
if (popbit()) color+=fac; fac<<=1;
}
}
vipdone:
globalbmp[(x+2-xx)*EXT+y+2-yy]+=color;
}
staylow:
asm dec xx
asm jz xdone
asm jmp nextx
xdone:
asm dec yy
asm jz ydone
asm jmp newx
ydone:
}
// FINEMASK
void finemask(byte *bits,byte *bmp,word no)
{
static long bit_ptr;
bit_ptr=(long)bits;
if (!no)
datas=(byte *)bit_ptr;
globalbmp=bmp;
datamask=128;
ctest((no%6)*(EXT/6),(no/6)*(EXT/6),(EXT/6));
while (datamask<0x80)
popbit();
}
// DRAWNEAR
void drawnear(word sx,word sy,word height, word width,long bmp_ptr)
{
#ifdef NODRAW
return;
#endif
if (!width || !height)
return;
byte nearstarty_ss=nearstarty;
word start,startdi;
byte br0kx=nearstartx;
asm pusha
asm push ds
asm mov dx,zoomvramptr
asm mov es,dx
asm mov dx,sx
asm mov cx,dx
asm shr dx,2
asm mov di,dx
asm mov dx,sy
asm shl dx,4
asm add di,dx
asm add dx,dx
asm add dx,dx
asm add di,dx // di = screenpos
asm mov bh,byte ptr innerfac // bx = innerfac
asm lds si,bmp_ptr
asm mov ch,byte ptr height // ch = y-teller
asm and cl,3
next_strip:
asm mov start,si
asm mov ax,0x0100+MAP_MASK
asm shl ah,cl
asm mov dx,SC_INDEX
asm out dx,ax
asm mov startdi,di
asm mov dx,79
asm mov bl,byte ptr width // bl = x-teller, ah = br0k-y
asm mov al,nearstarty_ss
next_down: // unroll!
asm movsb
asm add di,dx
asm add ah,bh
asm adc si,0
asm dec bl
asm jnz next_down
asm mov si,start
asm add si,EXT
asm add br0kx,bh
asm jnc nomoreright
asm add si,EXT
nomoreright:
asm mov di,startdi
asm inc cl
asm test cl,4
asm jz dontadvanceright
asm inc di
asm xor cl,cl
dontadvanceright:
asm dec ch
asm jnz next_strip
asm pop ds
asm popa
}
// DRAWFAR
void drawfar(word sx,word sy,word height, word width,long bmp_ptr)
{
#ifdef NODRAW
return;
#endif
if (!width || !height)
return;
word start,startdi;
byte br0kx=startx;
byte starty_ss=starty;
asm pusha
asm push ds
asm mov dx,zoomvramptr
asm mov es,dx
asm mov dx,sx
asm mov cx,dx
asm shr dx,2
asm mov di,dx
asm mov dx,sy
asm shl dx,4
asm add di,dx
asm add dx,dx
asm add dx,dx
asm add di,dx // di = screenpos
asm mov bh,byte ptr farfac // bx = innerfac
asm lds si,bmp_ptr
asm mov ch,byte ptr height // ch = y-teller
asm and cl,3
next_strip:
asm mov start,si
asm mov ax,0x0100+MAP_MASK
asm shl ah,cl
asm mov dx,SC_INDEX
asm out dx,ax
asm mov startdi,di
asm mov dx,80
asm mov al,byte ptr width // al = x-teller, ah = br0k-y
asm mov ah,starty_ss
next_down: // unroll!
asm mov bl,[si]
asm mov [es:di],bl
asm add di,dx
asm add ah,bh
asm adc si,0
asm dec al
asm jnz next_down
asm mov si,start
asm add br0kx,bh
asm jnc nomoreright
asm add si,EXT
nomoreright:
asm mov di,startdi
asm inc cl
asm test cl,4
asm jz dontadvanceright
asm inc di
asm xor cl,cl
dontadvanceright:
asm dec ch
asm jnz next_strip
asm pop ds
asm popa
return;
singleline:
}
// CONV
word conv(int x,int y,int tune)
{
float fx,fy;
float nearmov=tune/48.0;
float mov=nearmov/2;
fx=x-FRACX-EXT/2;
fy=y-FRACY-EXT/2;
fx/=EXT/2.0;
fy/=EXT/2.0;
float fxx=fx*(EXT/2)*(1-mov)+EXT/2;
float fyy=fy*(EXT/2)*(1-mov)+EXT/2;
int xxx=fxx;
int yyy=fyy;
fxx-=xxx;
fyy-=yyy;
startx=255.99*fxx;
starty=255.99*fyy;
farfac=255.99*(1-mov);
return yyy+EXT*xxx;
}
// SETZOOM
void setzoom(int zfac)
{
if (!zfac)
{
innerleft=FRACX+EXT/4;
innertop=FRACY+EXT/4;
innerlen=EXT/2+1;
innerfac=255;
return;
}
float mov=zfac/48.0;
float innerlenf=EXT/(2.0-mov);
innerlen=innerlenf;
float realinnerleft=FRACX+EXT/2-innerlen/2;
float realinnertop=FRACY+EXT/2-innerlen/2;
innertop=realinnertop;
innerleft=realinnerleft;
realinnerleft-=innerleft;
realinnertop-=innertop;
nearstartx=0;
nearstarty=0;
inneradr=innerleft+80*innertop;
innerfac=255*(2.0-mov);
innerfac-=256;
}
// DRAWZOOM
void drawzoom(long frac1,long frac2,int tune1)
{
float ftune=(tune1/48.0);
drawnear(innerleft,innertop,innerlen,innerlen,frac2);
int tlpluss,trpluss,cupluss,cdpluss;
tlpluss=conv(0,0,tune1);
if (tune1>0)
{
drawfar(FRACX,FRACY,EXT/2-innerlen/2,EXT,frac1+tlpluss);
cupluss=conv(innerleft,FRACY,tune1);
drawfar(innerleft,FRACY,innerlen,EXT/2-innerlen/2,frac1+cupluss);
trpluss=conv(FRACX+EXT/2+innerlen/2,FRACY,tune1);